﻿@namespace BlazorStrap.V4.Internal.Do.Not.Use
@typeparam TGridItem
@using BlazorComponentUtilities
@using Microsoft.AspNetCore.Components.Rendering
@using Microsoft.AspNetCore.Components.Web.Virtualization
@using BlazorStrap.V4.Components.DataGrid
@inherits BlazorStrap.Shared.Components.DataGrid.BSDataGridCoreBase<TGridItem>

<div class="d-flex flex-column">
    @if (Pagination != null && Pagination.PlacementIsTop)
    {
        <BSPagination Pages="Pagination.TotalPages" Value="Pagination.CurrentPage" ValueChanged="PageChangedAsync" Class="@Pagination.PlacementClass"/>
    }
    @if (IsResponsive)
    {
        <div class="@WrapperClassBuilder">
            <table class="@ClassBuilder">
                <thead>
                <tr>
                    @HeaderTemplate
                </tr>
                </thead>
                <tbody>
                @if (IsVirtualized)
                {
                    <Virtualize
                        TItem="(int rowIndex, TGridItem data)"
                        ItemContent="@(item => builder => RenderRow(builder, item.rowIndex, item.data))"
                        ItemsProvider="VirtualizedProvider"
                        ItemSize="@VirtualItemHeight"
                        OverscanCount="@VirtualOverscanCount"
                        Placeholder="@(placeholderContext => builder => RenderPlaceholderRow(builder, placeholderContext))"
                        @ref="VirtualizeRef"/>
                }
                else
                {
                    @BodyTemplate
                }
                </tbody>
                <tfoot>
                @FooterTemplate
                </tfoot>
            </table>
        </div>
    }
    else
    {
        <div class="@DataGridClass">
            <table class="@ClassBuilder">
                <thead>
                <tr>
                    @HeaderTemplate
                </tr>

                <FilterBuilder TGridItem="TGridItem" DataGrid="this"/>
                </thead>
                <tbody>
                @if (IsVirtualized)
                {
                    <Virtualize
                        TItem="(int rowIndex, TGridItem data)"
                        ItemContent="@(item => builder => RenderRow(builder, item.rowIndex, item.data))"
                        ItemsProvider="VirtualizedProvider"
                        ItemSize="@VirtualItemHeight"
                        OverscanCount="@VirtualOverscanCount"
                        Placeholder="@(placeholderContext => builder => RenderPlaceholderRow(builder, placeholderContext))"
                        @ref="VirtualizeRef"/>
                }
                else
                {
                    @BodyTemplate
                }
                </tbody>
                <tfoot>
                @FooterTemplate
                </tfoot>
            </table>
        </div>
    }
    @if (Pagination != null && Pagination.PlacementIsBottom)
    {
        <BSPagination Pages="Pagination.TotalPages" Value="Pagination.CurrentPage" ValueChanged="PageChangedAsync" Class="@Pagination.PlacementClass"/>
    }
</div>
@{ /*This looks odd but remember razor allows mixed html and C#.*/ }

@code
{
    protected override void RenderHeader(RenderTreeBuilder __builder)
    {
        @foreach (var column in ColumnState.Columns)
        {
            if(column.ColumnHeaderAccessor is null)
                column.CreateColumnHeaderAccessor();
            
            if (column.Header != null)
            {
                <th @key="column" style="@(column.SortOrder > 0 ? $"--sortOrder:{column.SortOrder};" : "")">
                    @{ column.BuildHeader(__builder, column.ColumnHeaderAccessor ?? throw new NullReferenceException("Column Header Accessor is not set")); }
                </th>
            }
            else
            {
                <th @key="column" style="@(column.SortOrder > 0 ? $"--sortOrder:{column.SortOrder};" : "")">
                    <div class="d-flex">
                        @if (column.ColumnOptions is not null)
                        {
                            <BSLink Class="grid-header-link" Target="@column.Id.ToString()">
                                <span class="@_menuClass"></span>
                            </BSLink>
                        }
                        @if (column.IsSortable)
                        {
                            <button class="me-auto @column.SortClassBuilder flex-grow-1" @onclick="(e) => ApplySortAsync(e, column.Id)">
                                @column.Title
                            </button>
                            @if (column.SortOrder > 0 && ColumnState.SortColumns.Count(x => x.Sorted) > 1)
                            {
                                <div>
                                    <span class="@MultiSortClass">@column.SortOrder</span>
                                </div>
                            }
                        }
                        else
                        {
                            @column.Title
                        }
                        @if (column.IsFilterable)
                        {
                            <BSLink Class="grid-header-link" OnClick="() => ColumnFilterClicked(column)">
                                <span class="@(ColumnFilters.Any(x => x.Property == column.PropertyPath) ? @_filterClass : @_filterClass + "-empty")"></span>
                            </BSLink>
                        }
                    </div>
                    @if (column.ColumnOptions is not null)
                    {
                        <BSDropdown DataId="@column.Id.ToString()" Target="@column.Id.ToString()">
                            <Content>
                                @(column.ColumnOptions(column.ColumnHeaderAccessor ?? throw new NullReferenceException("Column Header Accessor is not set")))
                            </Content>
                        </BSDropdown>
                    }
                </th>
            }
        }
    }

    protected override void RenderBody(RenderTreeBuilder __builder)
    {
        var ariaIndex = 2;

        @foreach (var item in DisplayedItems ?? new List<TGridItem>())
        {
            RenderRow(__builder, ariaIndex++, item);
        }
    }

    protected override void RenderRow(RenderTreeBuilder __builder, int rowIndex, TGridItem item)
    {
        var rowClass = "";
        var rowStyle = "";
        if (RowClassFunc != null) rowClass = RowClassFunc(item);
        if (RowStyleFunc != null) rowStyle = RowStyleFunc(item);
        <tr @key="item" aria-rowindex="@rowIndex" class="@(new CssBuilder().AddClass(rowClass).AddClass(rowStyle).NullIfEmpty())" style="@($"{rowStyle} {RowStyle}".ToNullString())">
            @foreach (var column in ColumnState.Columns)
            {
                if (column.ClassFunc != null) column.Class = column.ClassFunc(item);
                if (column.StyleFunc != null) column.Style = column.StyleFunc(item);

                <td @key="column" class="@column.ClassBuilder" style="@column.Style">
                        @{ column.CellContent(__builder, item); }
                </td>
            }
        </tr>
    }
    
    private void RenderPlaceholderRow(RenderTreeBuilder __builder, PlaceholderContext placeholderContext)
    {
        <tr aria-rowindex="@(placeholderContext.Index + 1)">
            @foreach (var column in ColumnState.Columns)
            {
                <td class="bs-datagrid-placeholder" @key="@column">@{ column.RenderPlaceholder(__builder, placeholderContext); }</td>
            }
        </tr>
    }

    protected override void RenderFooter(RenderTreeBuilder __builder)
    {
        @foreach (var column in ColumnState.Columns)
        {
            if (column.Footer != null)
            {
                __builder.AddContent(0, column.Footer);
            }
        }
    }

}